//===----------------------------------------------------------------------===//
//
//                         BusTub
//
// tuple.h
//
// Identification: src/include/storage/table/tuple.h
//
// Copyright (c) 2015-2019, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#pragma once

#include <string>
#include <vector>

#include "common/rid.h"

namespace benxdb {

/**
 * Tuple format:
 * ---------------------------------------------------------------------
 * | FIXED-SIZE or VARIED-SIZED OFFSET | PAYLOAD OF VARIED-SIZED FIELD |
 * ---------------------------------------------------------------------
 */
class Pair {
    friend class DataPage;

public:
    // Default constructor (to create a dummy tuple)
    Pair() = default;

    // constructor for creating a new tuple based on input value
    Pair(uint32_t rid, const Value value);

    // copy constructor, deep copy
    Pair(const Pair &other);

    // assign operator, deep copy
    Pair &operator=(const Pair &other);

    ~Pair() {
        if (allocated_) {
            delete[] data_;
        }
        allocated_ = false;
        data_ = nullptr;
    }
    // serialize tuple data_
    void SerializeTo(char *storage) const {
        memcpy(storage, &size_, sizeof(uint32_t));
        memcpy(storage + sizeof(int32_t), data_, size_);
    };

    // deserialize tuple data_(deep copy)
    void DeserializeFrom(const char *storage) {
        uint32_t size = *reinterpret_cast<const uint32_t *>(storage);
        // Construct a tuple.
        this->size_ = size;
        if (this->allocated_) {
            delete[] this->data_;
        }
        this->data_ = new char[this->size_];
        memcpy(this->data_, storage + sizeof(int32_t), this->size_);
        this->allocated_ = true;
    }

    // return RID of current tuple
    inline uint32_t GetRid() const { return rid_; }

    // Get the address of this tuple in the table's backing store
    inline char *GetData() const { return data_; }

    // Get length of the tuple, including varchar length
    inline uint32_t GetLength() const { return size_; }

    inline bool IsAllocated() { return allocated_; }

private:
    bool allocated_{false};  // is allocated?
    uint32_t rid_{0};              // if pointing to the table heap, the rid is valid
    uint32_t size_{0};
    char *data_{nullptr};
};

}  // namespace bustub
